use std::process::Command;

use crates_io_api::{Crate, CratesQueryBuilder, Error, SyncClient};

// 这是一个简单的启动函数
fn main() -> Result<(), Error> {
    // 创建一个客户端实例
    let client = SyncClient::new(
        "my_user_agent (my_contact@domain.com)",
        std::time::Duration::from_millis(1000),
    )
    .unwrap();

    let mut crates = vec![];

    // 获取分类为 "External FFI bindings" 的所有 crates
    get_crates_in_category(&mut crates, &client, "external-ffi-bindings")?;
    get_crates_in_category(&mut crates, &client, "api-bindings")?;

    for krate in crates {
        if let Some(rep) = krate.repository {
            // 克隆存储库到指定位置
            let status = Command::new("git")
                .arg("clone")
                .arg(rep) // 假设 rep 是存储库的 URL
                .current_dir("/home/yxz/ffi") // 替换成你想要存储库的目标文件夹
                .status()
                .expect("failed to execute process");

            if status.success() {
                println!("Repository cloned successfully!");
            } else {
                eprintln!("Failed to clone repository");
            }
        }
    }
    Ok(())
}

fn get_crates_in_category(
    crates: &mut Vec<Crate>,
    client: &SyncClient,
    category: &str,
) -> Result<(), Error> {
    // 设置初始页面和每页数量
    let mut page = 1;
    let per_page = 200; // crates.io API 的最大值

    loop {
        // 使用 crates.io API 的 search 方法查询分类
        let query = CratesQueryBuilder::new()
            .category(category)
            .page_size(per_page)
            .page(page)
            .build();

        let crates_page = client.crates(query).unwrap();

        // 遍历并打印当前页面的所有 crates 名称和最新版本
        for krate in &crates_page.crates {
            println!("{} ({})", krate.name, krate.max_version);
            crates.push(krate.clone());
        }

        // 检查是否已遍历所有页面
        if crates_page.crates.len() < per_page.try_into().unwrap() {
            break; // 如果这一页不是满的，说明已经是最后一页了
        }

        page += 1;
    }

    Ok(())
}
